/***************************************************************************
 *   mgpi_errors.h - Errors Handling Interface Declarations                *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _ERRORS_H
#define _ERRORS_H

#ifdef __cplusplus
extern "C" {
#endif

#include <assert.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#ifdef WIN32
#define MGPI_API __declspec (dllexport)
#define MGPI_IMPORT __declspec (dllimport)
#else
#define MGPI_API
#define MGPI_IMPORT
#endif

#define MGPI_NOERROR "Nothing went wrong whatsoever..."                         /** default inforamation message */

#pragma pack(push,1)

    typedef struct _msgnode {
        struct _msgnode *next;
        struct _msgnode *prev;
        char *message;                                                          /** message string */
        void *vparam;                                                           /** auxiliary pointer */
    } msgnode_t;                                                                /** message node */

#pragma pack(pop)

    /**
     * Gets the short message string.
     */
    const char MGPI_API *MGPI_GetMessage(void);

    /**
     * Causes the message string to be set to a proper message containing given string.
     */
    void MGPI_API MGPI_PostMessage(const char *message, void *ptr);

    /**
     * Adds a message to the messages list with the given formated message string.
     */
    void MGPI_API MGPI_PostMessagef(const char *fromat, ...);

    /**
     * Gets the last called message string.
     */
    const char MGPI_API *MGPI_GetLastMessage(void);

    /**
     * Gets the last called message node.
     */
    msgnode_t MGPI_API *MGPI_GetLastMessageNode(void);

    /**
     * Prints all messages from the list to the given stream.
     */
    int MGPI_API MGPI_GetMessages(FILE *stream);

    /**
     * Function called at the engine stop, just before shot down. In here one
     * can put the finalization code e.g. releasing resources.
     */
    extern MGPI_IMPORT void ENGINE_Exit(void);

    /**
     * Posts a GL error.
     */
    void debug_PostGLError(const char *msg);

    /**
     * Posts a SDL error.
     */
    void debug_PostSDLError(const char *msg);

    /**
     * Gets time form the given system time in seconds.
     */
    void debug_GetTime(double *t);

#ifdef WIN32
#ifdef __FUNCTION__
#define __FUN__ __FUNCTION__
#endif
#else
// In gcc use flag: -std=c99
#if __STDC_VERSION__ >= 199901L
#define __FUN__ __func__
#else
#define __FUN__ "[function?]"
#endif
#endif

#ifdef __FUN__
#define MGPI_MESSAGE(msg) MGPI_PostMessagef("%s: %s", __FUN__, msg)
#endif	

#ifdef __cplusplus
}
#endif

#endif
